﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Transactions;
using SMA.GENTEv1.Dados;

namespace SMA.GENTEv1
{
    public class PessoaAdvertencia
    {
        #region Variaveis Membro
        private int _idAdvertencia;
        private TipoSuspensao _tipoSuspensao;
        private Pessoa _pessoa;
        private Pessoa _advertidoPor;
        private DateTime _dataAdvertencia;
        private DateTime? _dataInicioSuspensao;
        private DateTime? _dataFimSuspensao;
        private string _obs;
        private string _path;
        private GENTEEntities _context;
        #endregion

        #region Parametros
        public int IdAdvertencia
        {
            get { return _idAdvertencia; }
            set { _idAdvertencia = value; }
        }

        public TipoSuspensao TipoSuspensao
        {
            get { return _tipoSuspensao; }
            set { _tipoSuspensao = value; }
        }

        public Pessoa Pessoa
        {
            get { return _pessoa; }
            set { _pessoa = value; }
        }

        public Pessoa AdvertidoPor
        {
            get { return _advertidoPor; }
            set { _advertidoPor = value; }
        }

        public DateTime DataAdvertencia
        {
            get { return _dataAdvertencia; }
            set { _dataAdvertencia = value; }
        }

        public DateTime? DataInicioSuspensao
        {
            get { return _dataInicioSuspensao; }
            set { _dataInicioSuspensao = value; }
        }

        public DateTime? DataFimSuspensao
        {
            get { return _dataFimSuspensao; }
            set { _dataFimSuspensao = value; }
        }

        public string Obs
        {
            get { return _obs; }
            set { _obs = value; }
        }

        public string Path
        {
            get { return _path; }
            set { _path = value; }
        }
        #endregion

        #region Construtores
        public PessoaAdvertencia()
        {
            try
            {
                _context = new GENTEEntities();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public PessoaAdvertencia(int idAdvertencia)
        {
            try
            {
                _context = new GENTEEntities();
                Carregar(idAdvertencia);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Métodos Privados
        private void Carregar(int idAdvertencia)
        {
            try
            {
                var consulta = from ad in _context.tab_pessoa_advertencia
                               where ad.id_advertencia == idAdvertencia
                               select new
                               {
                                   ad.id_advertencia,
                                   ad.tab_tipo_suspensao.id_tipo_suspensao,
                                   ad.tab_pessoa.Id_pessoa,
                                   id_advertido_por = ad.tab_pessoa1.Id_pessoa,
                                   ad.data_advertencia,
                                   ad.data_inicio_suspensao,
                                   ad.data_fim_suspensao,
                                   ad.obs,
                                   ad.path
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    this.IdAdvertencia = list.id_advertencia;
                    this.TipoSuspensao = new TipoSuspensao(list.id_tipo_suspensao);
                    this.Pessoa = new Pessoa(list.Id_pessoa, true);
                    this.AdvertidoPor = new Pessoa(list.id_advertido_por, true);
                    this.DataAdvertencia = list.data_advertencia;
                    this.DataInicioSuspensao = list.data_inicio_suspensao;
                    this.DataFimSuspensao = list.data_fim_suspensao;
                    this.Obs = list.obs;
                    this.Path = list.path;
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private bool VerificaCadastro()
        {
            try
            {
                bool valida = false;

                if (this._tipoSuspensao == null)
                    throw new Exception("É necessário informar o tipo de suspensão!");

                if (this._tipoSuspensao.IdTipoSuspensao == 0)
                    throw new Exception("É necessário informar o tipo de suspensão!");

                if (this._pessoa == null)
                    throw new Exception("É necessário informar o associado!");

                if (this._pessoa.IdPessoa == 0)
                    throw new Exception("É necessário informar o associado!");

                if (this._advertidoPor == null)
                    throw new Exception("É necessário informar por qual associado foi advertido!");

                if (this._advertidoPor.IdPessoa == 0)
                    throw new Exception("É necessário informar por qual associado foi advertido!");

                if (this._dataAdvertencia == null)
                    throw new Exception("É necessário informar a data de advertência!");

                if ((this._tipoSuspensao.IdTipoSuspensao == 2) || (this._tipoSuspensao.IdTipoSuspensao == 3))
                {
                    switch (this._tipoSuspensao.IdTipoSuspensao)
                    {
                        case 3:
                            if (this._dataInicioSuspensao == null)
                                throw new Exception("É necessário informar a data de início da suspensão!");

                            if (this._dataFimSuspensao == null)
                                throw new Exception("É necessário informa a data de término da suspensão!");
                            break;
                    }
                    if (this._path == string.Empty)
                        throw new Exception("Advertência formal ou suspensão deve ser acompanhada do documento correspondente!");
                }

                valida = true;
                return valida;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private int RetornaIdAdvertencia()
        {
            try
            {
                int idadvertencia = 0;

                var consulta = (from advertencia in _context.tab_pessoa_advertencia
                                orderby advertencia.id_advertencia descending
                                select new
                                {
                                    advertencia.id_advertencia
                                }).Take(1);

                idadvertencia = consulta.ToList()[0].id_advertencia;

                return idadvertencia;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void AtualizarPath(string path)
        {
            try
            {
                tab_pessoa_advertencia tabPessoaAdvertencia = (from advertencia in _context.tab_pessoa_advertencia
                                                               where advertencia.id_advertencia == this._idAdvertencia
                                                               select advertencia).First();

                tabPessoaAdvertencia.path = path;
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public void AtualizarStatusSuspensao()
        {
            try
            {
                if ((this._tipoSuspensao.IdTipoSuspensao == 3) && (DateTime.Today <= this._dataFimSuspensao))
                {
                    tab_pessoa tabPessoa = (from pessoa in _context.tab_pessoa
                                            where pessoa.Id_pessoa == this._pessoa.IdPessoa
                                            select pessoa).First();

                    tabPessoa.tab_pessoa_statusReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_pessoa_status", "id_status_pessoa", 4);  // 4 - Suspensão(a)
                    _context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Metodos Publicos

        #region Metodos de Selecao
        public List<PessoaAdvertencia> SelectAll()
        {
            try
            {
                List<PessoaAdvertencia> advertencias = new List<PessoaAdvertencia>();

                var consulta = from ad in _context.tab_pessoa_advertencia
                               select new
                               {
                                   ad.id_advertencia,
                                   ad.tab_tipo_suspensao.id_tipo_suspensao,
                                   ad.tab_pessoa.Id_pessoa,
                                   id_advertido_por = ad.tab_pessoa1.Id_pessoa,
                                   ad.data_advertencia,
                                   ad.data_inicio_suspensao,
                                   ad.data_fim_suspensao,
                                   ad.obs,
                                   ad.path
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    PessoaAdvertencia advertencia = new PessoaAdvertencia();
                    advertencia.IdAdvertencia = list.id_advertencia;
                    advertencia.TipoSuspensao = new TipoSuspensao(list.id_tipo_suspensao);
                    advertencia.Pessoa = new Pessoa(list.Id_pessoa, true);
                    advertencia.AdvertidoPor = new Pessoa(list.id_advertido_por, true);
                    advertencia.DataAdvertencia = list.data_advertencia;
                    advertencia.DataInicioSuspensao = list.data_inicio_suspensao;
                    advertencia.DataFimSuspensao = list.data_fim_suspensao;
                    advertencia.Obs = list.obs;
                    advertencia.Path = list.path;

                    advertencias.Add(advertencia);
                }

                return advertencias;
            }
            catch (Exception ex)
            {    
                throw ex;
            }
        }
        public List<PessoaAdvertencia> SelectPorPessoa(int idPessoa)
        {
            try
            {
                List<PessoaAdvertencia> advertencias = new List<PessoaAdvertencia>();

                var consulta = from ad in _context.tab_pessoa_advertencia
                               where ad.tab_pessoa.Id_pessoa == idPessoa
                               select new
                               {
                                   ad.id_advertencia,
                                   ad.tab_tipo_suspensao.id_tipo_suspensao,
                                   ad.tab_pessoa.Id_pessoa,
                                   id_advertido_por = ad.tab_pessoa1.Id_pessoa,
                                   ad.data_advertencia,
                                   ad.data_inicio_suspensao,
                                   ad.data_fim_suspensao,
                                   ad.obs,
                                   ad.path
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    PessoaAdvertencia advertencia = new PessoaAdvertencia();
                    advertencia.IdAdvertencia = list.id_advertencia;
                    advertencia.TipoSuspensao = new TipoSuspensao(list.id_tipo_suspensao);
                    advertencia.Pessoa = new Pessoa(list.Id_pessoa, true);
                    advertencia.AdvertidoPor = new Pessoa(list.id_advertido_por, true);
                    advertencia.DataAdvertencia = list.data_advertencia;
                    advertencia.DataInicioSuspensao = list.data_inicio_suspensao;
                    advertencia.DataFimSuspensao = list.data_fim_suspensao;
                    advertencia.Obs = list.obs;
                    advertencia.Path = list.path;

                    advertencias.Add(advertencia);
                }

                return advertencias;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Metodos de Persistencia
        public void Salvar()
        {
            try
            {
                if (VerificaCadastro())
                {
                    if (this._idAdvertencia == 0)
                    {
                        tab_pessoa_advertencia tabPessoaAdvertencia = new tab_pessoa_advertencia();

                        tabPessoaAdvertencia.tab_tipo_suspensaoReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_tipo_suspensao", "id_tipo_suspensao", this._tipoSuspensao.IdTipoSuspensao);
                        tabPessoaAdvertencia.tab_pessoaReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_pessoa", "Id_pessoa", this._pessoa.IdPessoa);
                        tabPessoaAdvertencia.tab_pessoa1Reference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_pessoa", "Id_pessoa", this._advertidoPor.IdPessoa);
                        tabPessoaAdvertencia.data_advertencia = this._dataAdvertencia;
                        if (this._dataInicioSuspensao != null)
                            tabPessoaAdvertencia.data_inicio_suspensao = this._dataInicioSuspensao;
                        if (this._dataFimSuspensao != null)
                            tabPessoaAdvertencia.data_fim_suspensao = this._dataFimSuspensao;
                        tabPessoaAdvertencia.obs = this._obs;

                        _context.AddTotab_pessoa_advertencia(tabPessoaAdvertencia);
                        _context.SaveChanges();

                        this._idAdvertencia = RetornaIdAdvertencia();

                        string _nomearquivo = "";
                        TipoDocumentoPessoa tipodocto = new TipoDocumentoPessoa();
                        _nomearquivo = tipodocto.ObterNomeDocumento(this._pessoa.IdPessoa, TipoDocumentoPessoa.TipoDocumento.Advertencias_Suspensoes, this._idAdvertencia.ToString());

                        AtualizarPath(this._path + _nomearquivo);
                        this._path = this._path + _nomearquivo;

                        AtualizarStatusSuspensao();
                    }
                    else
                    {
                        tab_pessoa_advertencia tabPessoaAdvertencia = (from advertencia in _context.tab_pessoa_advertencia
                                                                       where advertencia.id_advertencia == this._idAdvertencia
                                                                       select advertencia).First();

                        tabPessoaAdvertencia.tab_tipo_suspensaoReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_tipo_suspensao", "id_tipo_suspensao", this._tipoSuspensao.IdTipoSuspensao);
                        tabPessoaAdvertencia.tab_pessoaReference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_pessoa", "Id_pessoa", this._pessoa.IdPessoa);
                        tabPessoaAdvertencia.tab_pessoa1Reference.EntityKey = new System.Data.EntityKey("GENTEEntities.tab_pessoa", "Id_pessoa", this._advertidoPor.IdPessoa);
                        tabPessoaAdvertencia.data_advertencia = this._dataAdvertencia;
                        if (this._dataInicioSuspensao != null)
                            tabPessoaAdvertencia.data_inicio_suspensao = this._dataInicioSuspensao;
                        if (this._dataFimSuspensao != null)
                            tabPessoaAdvertencia.data_fim_suspensao = this._dataFimSuspensao;
                        tabPessoaAdvertencia.obs = this._obs;

                        if (this._path != string.Empty)
                        {
                            string _nomearquivo = "";
                            TipoDocumentoPessoa tipodocto = new TipoDocumentoPessoa();
                            _nomearquivo = tipodocto.ObterNomeDocumento(this._pessoa.IdPessoa, TipoDocumentoPessoa.TipoDocumento.Advertencias_Suspensoes, this._idAdvertencia.ToString());

                            tabPessoaAdvertencia.path = this._path + _nomearquivo;
                            this._path = this._path + _nomearquivo;
                        }

                        _context.SaveChanges();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Excluir(string _caminhoDoc)
        {
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    var consulta = from advertencia in _context.tab_pessoa_advertencia
                                   where advertencia.id_advertencia == this._idAdvertencia
                                   select advertencia;

                    var listConsulta = consulta.ToList();

                    string _documento = "";
                    foreach (var list in listConsulta)
                    {
                        _documento = list.path;
                        _context.DeleteObject(list);
                        _context.SaveChanges();

                        System.IO.FileInfo fileInfo = new System.IO.FileInfo(_documento);
                        _documento = _caminhoDoc + @"\" + fileInfo.Name;

                        if ((_documento != "") && (System.IO.File.Exists(_documento)))
                            System.IO.File.Delete(_documento);

                    }

                    scope.Complete();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
        public void Excluir()
        {
            try
            {
                if (this.IdAdvertencia != 0)
                {
                    tab_pessoa_advertencia tabPessoaAdvertencia = (from advertencia in _context.tab_pessoa_advertencia
                                                                   where advertencia.id_advertencia == this._idAdvertencia
                                                                   select advertencia).First(); ;

                    _context.DeleteObject(tabPessoaAdvertencia);
                    _context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #endregion


        //public void Carregar(int _advertencia, bool _carregaTipoSuspensao, bool _carregaPessoa, bool _carregaAdvertidoPor)
        //{
        //    try
        //    {
        //        var consulta = (from advertencia in _context.tab_pessoa_advertencia
        //                        where advertencia.id_advertencia == _advertencia
        //                        select new
        //                        {
        //                            advertencia.id_advertencia,
        //                            advertencia.tab_tipo_suspensao.id_tipo_suspensao,
        //                            advertencia.tab_pessoa.Id_pessoa,
        //                            id_advertido_por = advertencia.tab_pessoa1.Id_pessoa,
        //                            advertencia.data_advertencia,
        //                            advertencia.data_inicio_suspensao,
        //                            advertencia.data_fim_suspensao,
        //                            advertencia.obs,
        //                            advertencia.path
        //                        });

        //        var listConsulta = consulta.ToList();

        //        foreach (var list in listConsulta)
        //        {
        //            this._idAdvertencia = list.id_advertencia;
        //            this._tipoSuspensao = new TipoSuspensao(list.id_tipo_suspensao, _carregaTipoSuspensao);
        //            this._tipoSuspensao = new TipoSuspensao { IdTipoSuspensao = list.id_tipo_suspensao };

        //            if (_carregaPessoa)
        //                this._pessoa = new Pessoa(list.Id_pessoa);
        //            else
        //            {
        //                this._pessoa = new Pessoa();
        //                this._pessoa.IdPessoa = list.Id_pessoa;
        //            }

        //            if (_carregaAdvertidoPor)
        //                this._advertidoPor = new Pessoa(list.id_advertido_por);
        //            else
        //            {
        //                this._advertidoPor = new Pessoa();
        //                this._advertidoPor.IdPessoa = list.id_advertido_por;
        //            }

        //            this._dataAdvertencia = list.data_advertencia;
        //            this._dataInicioSuspensao = list.data_inicio_suspensao;
        //            this._dataFimSuspensao = list.data_fim_suspensao;
        //            this._obs = list.obs;
        //            this._path = list.path;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }
        //}

        //private static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
        //{
        //    if (null == valueSelector)
        //    {
        //        throw new
        //            ArgumentNullException("valueSelector");
        //    }
        //    if (null == values) { throw new ArgumentNullException("values"); }

        //    ParameterExpression p = valueSelector.Parameters.Single();
        //    if (!values.Any())
        //    {
        //        return e => false;
        //    }

        //    var equals = values.Select(value =>
        //    (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value,
        //    typeof(TValue))));
        //    var body = equals.Aggregate<Expression>((accumulate, equal) =>
        //    Expression.Or(accumulate, equal));
        //    return Expression.Lambda<Func<TElement, bool>>(body, p);
        //}
        
        //public List<PessoaAdvertencia> SelectAdvertencias(int _pessoa, bool _carregaTipoSuspensao, bool _carregaPessoa, bool _carregaAdvertidoPor)
        //{
        //    try
        //    {
        //        List<PessoaAdvertencia> listAdvertencias = new List<PessoaAdvertencia>();
                
        //        var consulta = (from advertencia in _context.tab_pessoa_advertencia
        //                        where advertencia.tab_pessoa.Id_pessoa == _pessoa
        //                        select new
        //                        {
        //                            advertencia.id_advertencia,
        //                            advertencia.tab_tipo_suspensao.id_tipo_suspensao,
        //                            advertencia.tab_pessoa.Id_pessoa,
        //                            id_advertido_por = advertencia.tab_pessoa1.Id_pessoa,
        //                            advertencia.data_advertencia,
        //                            advertencia.data_inicio_suspensao,
        //                            advertencia.data_fim_suspensao,
        //                            advertencia.obs,
        //                            advertencia.path
        //                        });

        //        var listConsulta = consulta.ToList();

        //        foreach (var list in listConsulta)
        //        {
        //            PessoaAdvertencia advertencia = new PessoaAdvertencia();
        //            advertencia.IdAdvertencia = list.id_advertencia;
        //            advertencia.TipoSuspensao = new TipoSuspensao(list.id_tipo_suspensao, _carregaTipoSuspensao);

        //            if (_carregaPessoa)
        //                advertencia.Pessoa = new Pessoa(list.Id_pessoa);
        //            else
        //            {
        //                advertencia.Pessoa = new Pessoa();
        //                advertencia.Pessoa.IdPessoa = list.Id_pessoa;
        //            }

        //            if (_carregaAdvertidoPor)
        //                advertencia.AdvertidoPor = new Pessoa(list.id_advertido_por);
        //            else
        //            {
        //                advertencia.AdvertidoPor = new Pessoa();
        //                advertencia.AdvertidoPor.IdPessoa = list.id_advertido_por;
        //            }

        //            advertencia.DataAdvertencia = list.data_advertencia;
        //            advertencia.DataInicioSuspensao = list.data_inicio_suspensao;
        //            advertencia.DataFimSuspensao = list.data_fim_suspensao;
        //            advertencia.Obs = list.obs;
        //            advertencia.Path = list.path;

        //            listAdvertencias.Add(advertencia);
        //        }

        //        return listAdvertencias;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }
        //}

        //public List<PessoaAdvertencia> SelectAdvertencias(int[] _tiposuspensao, DateTime _dataInicial, DateTime _dataFinal,
        //                                                  bool _carregaTipoSuspensao, bool _carregaPessoa, bool _carregaAdvertidoPor)
        //{
        //    try
        //    {
        //        List<PessoaAdvertencia> listAdvertencias = new List<PessoaAdvertencia>();

        //        var consulta = (from advertencia in _context.tab_pessoa_advertencia.Where((BuildContainsExpression<tab_pessoa_advertencia, int>(item => item.tab_tipo_suspensao.id_tipo_suspensao, _tiposuspensao)))
        //                        where advertencia.data_advertencia >= _dataInicial
        //                        && advertencia.data_advertencia <= _dataFinal
        //                        select new
        //                        {
        //                            advertencia.id_advertencia,
        //                            advertencia.tab_tipo_suspensao.id_tipo_suspensao,
        //                            advertencia.tab_pessoa.Id_pessoa,
        //                            id_advertido_por = advertencia.tab_pessoa1.Id_pessoa,
        //                            advertencia.data_advertencia,
        //                            advertencia.data_inicio_suspensao,
        //                            advertencia.data_fim_suspensao,
        //                            advertencia.obs,
        //                            advertencia.path
        //                        });

        //        var listConsulta = consulta.ToList();

        //        foreach (var list in listConsulta)
        //        {
        //            PessoaAdvertencia advertencia = new PessoaAdvertencia();
        //            advertencia.IdAdvertencia = list.id_advertencia;
        //            advertencia.TipoSuspensao = new TipoSuspensao(list.id_tipo_suspensao, _carregaTipoSuspensao);

        //            if (_carregaPessoa)
        //                advertencia.Pessoa = new Pessoa(list.Id_pessoa);
        //            else
        //            {
        //                advertencia.Pessoa = new Pessoa();
        //                advertencia.Pessoa.IdPessoa = list.Id_pessoa;
        //            }

        //            if (_carregaAdvertidoPor)
        //                advertencia.AdvertidoPor = new Pessoa(list.id_advertido_por);
        //            else
        //            {
        //                advertencia.AdvertidoPor = new Pessoa();
        //                advertencia.AdvertidoPor.IdPessoa = list.id_advertido_por;
        //            }

        //            advertencia.DataAdvertencia = list.data_advertencia;
        //            advertencia.DataInicioSuspensao = list.data_inicio_suspensao;
        //            advertencia.DataFimSuspensao = list.data_fim_suspensao;
        //            advertencia.Obs = list.obs;
        //            advertencia.Path = list.path;

        //            listAdvertencias.Add(advertencia);
        //        }

        //        return listAdvertencias;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }
        //}        
        
    }
}
